// app/api/files/[projectId]/share/route.ts import { NextRequest, NextResponse } from 'next/server'; import { getServerSession } from 'next-auth/next'; import { authOptions } from '@/app/api/auth/[...nextauth]/route' import { FileService, type FileAccessContext } from '@/lib/services/fileService'; import { z } from 'zod'; const createShareSchema = z.object({ fileId: z.string().uuid(), accessLevel: z.enum(['view_only', 'view_download']).optional(), password: z.string().optional(), expiresAt: z.string().datetime().optional(), maxDownloads: z.number().positive().optional(), sharedWithEmail: z.string().email().optional(), }); // 공유 링크 생성 export async function POST( request: NextRequest, { params }: { params: { projectId: string } } ) { try { const session = await getServerSession(authOptions); if (!session?.user) { return NextResponse.json({ error: '인증이 필요합니다' }, { status: 401 }); } const body = await request.json(); const validatedData = createShareSchema.parse(body); const context: FileAccessContext = { userId: session.user.id, userDomain: session.user.domain || 'partners', userEmail: session.user.email, ipAddress: request.ip || request.headers.get('x-forwarded-for') || undefined, userAgent: request.headers.get('user-agent') || undefined, }; const fileService = new FileService(); const shareToken = await fileService.createShareLink( validatedData.fileId, { ...validatedData, expiresAt: validatedData.expiresAt ? new Date(validatedData.expiresAt) : undefined, }, context ); const shareUrl = `${process.env.NEXT_PUBLIC_APP_URL}/shared/${shareToken}`; return NextResponse.json({ shareToken, shareUrl, success: true }); } catch (error) { if (error instanceof z.ZodError) { return NextResponse.json( { error: '잘못된 요청 데이터', details: error.errors }, { status: 400 } ); } if (error instanceof Error && error.message.includes('권한')) { return NextResponse.json( { error: error.message }, { status: 403 } ); } console.error('공유 링크 생성 오류:', error); return NextResponse.json( { error: '공유 링크 생성에 실패했습니다' }, { status: 500 } ); } }